/**
 * 源码名称：jQueryValidate.js
 * 实现功能：基于jQuery，以最简单的方式提供表单校验功能
 * 作者主页：http://www.miaoqiyuan.cn/
 * 联系邮箱：mqycn@126.com
 * 使用说明：http://www.miaoqiyuan.cn/p/jquery-validate-qy
 * 最新版本：http://git.oschina.net/mqycn/jQueryValidate
 */

(function($) {
    $.fn.extend({

        /**
         * 验证输入框是否合法
         */
        'validate': function(pattern, errMsg, styles) {

            if ($(this).attr('type') == 'submit' || $(this).attr('type') == 'button') {
                return true;
            }

            $._validateCache = $._validateCache || {};

            var key = $(this).data('validate-cache') || 'valid_' + $(this).attr('name') + '_' + parseInt(Math.random() * 1000000);
            var list = $._validateCache[key] || [];
            var data = {};
            var defaultStyle = {
                'success': { //默认的成功样式
                    'border-color': '#4FC800',
                    'color': '#4FC800',
                    'background': '#E4FFDB',
                },
                'error': { //默认的失败样式
                    'border-color': '#C00',
                    'color': '#C00',
                    'background': '#F09692'
                },
                'tips': { //默认的提示框样式
                    'background': '#C00',
                    'color': '#FFF',
                    'padding': '2px 5px',
                    'border': 0,
                    'border-radius': '5px'
                }
            };

            //根据配置读取样式
            var styles = {};
            if (typeof pattern == 'object') {
                if ((pattern instanceof Array)) {
                    styles = errMsg;
                } else {
                    styles = pattern.styles || errMsg;
                }
            }
            styles = styles || {};
            styles.error = styles.error || defaultStyle.error;
            styles.success = styles.success || defaultStyle.success;
            styles.tips = styles.tips || defaultStyle.tips;

            if (!!pattern) {
                //添加验证规则
                var fun;

                switch (typeof pattern) {
                    case 'function':
                        fun = pattern;
                        break;
                    case 'string':
                        fun = function() {
                            return $(this).val().match(new RegExp(pattern));
                        };
                        break;
                    case 'object':
                        if (pattern instanceof Array) {
                            /** 后端的规则(比如PHP)，通过模版传入
                             *  array(
                             *    'username',
                             *    '/^[A-Za-z0-9]{5,15}$/',
                             *    '用户名只能为5-10位的字母或数字组成'
                             *  );
                             */
                            return $(this).validate(pattern[1].substr(1, pattern[1].length - 2), pattern[2], styles);
                        } else {
                            /**
                             * {
                             *    fun : function(){}
                             *    error : '出错了'
                             * }
                             */
                            fun = pattern.fun || function() { return true; };
                            errMsg = pattern.error || '验证出错';
                        }
                        break;

                    default:
                        throw new Error('Bad Type');
                }

                list.push({
                    fun: fun,
                    error: errMsg,
                    styles: styles,
                });

                $(this).data('validate-cache', key);
                $._validateCache[key] = list;

                return $(this);
            } else {
                //验证是否有效
                for (var i = 0; i < list.length; i++) {
                    data = list[i];
                    //读取最后一个样式配置，无论成功失败都会被覆盖前一个
                    styles = data.styles;
                    if (!data.fun.call(this)) {
                        return $(this).validateStatus.call(this, false, styles, data);
                    }
                }
                return $(this).validateStatus.call(this, true, styles);
            }
        },

        /**
         * 显示错误提示
         */
        validateStatus: function(status, styles, data) {
            var key = $(this).data('vaildate-target');
            if (!status) {
                if (!key) {
                    key = 'tips_' + $(this).attr('name') + '_' + parseInt(Math.random() * 100000);
                    $(this).data('vaildate-target', key);
                }
                if ($(this).val() == '') {
                    $(this).attr('placeholder', '').focus();
                }
                $(this).css(styles.error);
                $('input').offset();

                var $tips = $('#' + key);
                var $this = $(this);
                if ($tips.length == 0) {
                    //没有创建过提示框，自动创建
                    $('body').append('<div id="' + key + '" style="position:absolute;text-align:center;opacity:0.8;"><div class="vaildate-tips-body"></div><div class="vaildate-tips-array"></div></div>');
                    $tips = $('#' + key);
                }
                $tips.find('.vaildate-tips-body').html(data.error).css(styles.tips);
                $tips.find('.vaildate-tips-array').width(0).height(0).css({
                    'border': 'solid 5px ' + styles.tips.background,
                    'border-left-color': 'transparent',
                    'border-right-color': 'transparent',
                    'border-bottom-color': 'transparent',
                    'margin-left': '30px',
                    'margin-top': '0',
                });
                $tips.css('top', $this.offset().top - $tips.height() + 4);
                $tips.css('left', $this.offset().left + 10);
                $tips.show();
            } else {
                $(this).css(styles.success);
                if (!!key) {
                    var $tips = $('#' + key);
                    if (!!$tips) {
                        $tips.hide();
                    }
                }
            }
            return status;
        },

        /**
         * 表单验证
         */
        validateForm: function(validateOnce) {
            var status = true;
            var form = $(this)[0];
            for (var i = 0; i < form.length; i++) {
                var valid = $(form[i]).validate();
                if (!!validateOnce) {
                    if (valid == false) {
                        return false;
                    }
                }
                status = valid && status;
            }
            return status;
        },

        /**
         * 表单绑定
         */
        validateBind: function(name) {
            if ($(this).is('form')) {
                var form = $(this)[0];
                for (var i = 0; i < form.length; i++) {
                    $(form[i]).validateBind(name);
                }
            } else {
                $(this).on(name, function() {
                    $(this).validate();
                });
            }
            return $(this);
        }
    });
})(jQuery);